#include "MQTT_Client.h"
#include "rc522.h"

// WiFi配置
const char* ssid = "OPPO Find X8"; // 换成你自己的热点名称
const char* pass = "@dwj080900";   // 热点密码

// MQTT配置
const char* broker = "broker.emqx.io";
int port = 1883;
const char* inTopic = "Android_Get"; // 这两个topic也要改成自己的
const char* outTopic = "Android_Set";

// MQTT客户端对象
WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);

String inputString = "";

void setupWiFi() {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    WiFi.mode(WIFI_STA);
    WiFi.begin(ssid, pass);
    
    while (WiFi.status() != WL_CONNECTED) {
        Serial.print(".");
        delay(500);
    }
    
    Serial.println("You're connected to the network");
    Serial.println();
}

void setupMQTT() {
    mqttClient.setId("mqttx_da5aa4aa"); // 这个也要换成自己的
    
    mqttClient.setUsernamePassword("admin", "password"); // 这个也要换成自己的
    
    Serial.print("Attempting to connect to the MQTT broker: ");
    Serial.println(broker);
    
    if (!mqttClient.connect(broker, port)) {
        Serial.print("MQTT connection failed! Error code = ");
        Serial.println(mqttClient.connectError());
        
        while (1);
    }
    
    Serial.println("You're connected to the MQTT broker!");
    Serial.println();
    
    mqttClient.onMessage(onMqttMessage);
    
    Serial.print("Subscribing to topic: ");
    Serial.println(inTopic);
    Serial.println();
    
    int subscribeQos = 1;
    mqttClient.subscribe(inTopic, subscribeQos);
    
    Serial.print("Waiting for messages on topic: ");
    Serial.println(inTopic);
    Serial.println();
}

void mqttLoop() {
    mqttClient.poll();
}

void onMqttMessage(int messageSize) {
    Serial.print("Received a message with topic '");
    Serial.print(mqttClient.messageTopic());
    Serial.print("', duplicate = ");
    Serial.print(mqttClient.messageDup() ? "true" : "false");
    Serial.print(", QoS = ");
    Serial.print(mqttClient.messageQoS());
    Serial.print(", retained = ");
    Serial.print(mqttClient.messageRetain() ? "true" : "false");
    Serial.print("', length ");
    Serial.print(messageSize);
    Serial.println(" bytes:");
    
    inputString = "";
    while (mqttClient.available()) {
        char inChar = (char)mqttClient.read();
        inputString += inChar;
    }
    
    Serial.print("Message content: ");
    Serial.println(inputString);
    
    // 处理MQTT命令
    processMQTTCommand(inputString);
    
    Serial.println();
}

void processMQTTCommand(const String& command) {
    String cmd = command;
    cmd.trim();
    
    // 尝试解析JSON格式的命令
    DynamicJsonDocument doc(512);
    DeserializationError error = deserializeJson(doc, command);
    
    if (error) {
        // 如果不是JSON格式，按原来的纯文本命令处理
        cmd.toLowerCase();
        
        if (cmd == "write") {
            currentState = WAITING_CARD;
            String response = "请刷卡以注册卡号...";
            Serial.println(response);
            sendCommandResponse("write", response);
        }
        else if (cmd == "read") {
            printAllRegisteredCards();
            String cardList = getAllRegisteredCardsString();
            int count = 0;
            if (cardList.length() > 0) {
                // 计算卡号数量（通过逗号分隔符）
                count = 1;
                for (int i = 0; i < cardList.length(); i++) {
                    if (cardList.charAt(i) == ',') count++;
                }
            }
            sendCardList(cardList, count);
            sendCommandResponse("read", "已获取所有注册的卡号列表");
        }
        else if (cmd == "delete") {
            deleteAllCards();
            String response = "所有卡号已删除";
            Serial.println(response);
            sendCommandResponse("delete", response);
        }
        else if (cmd.startsWith("delete ")) {
            byte uid[4];
            if (sscanf(cmd.c_str(), "delete %hhx %hhx %hhx %hhx",
                       &uid[0], &uid[1], &uid[2], &uid[3]) == 4) {
                String response;
                if (deleteSingleCard(uid)) {
                    response = "单卡删除成功";
                    Serial.println(response);
                } else {
                    response = "未找到该卡";
                    Serial.println(response);
                }
                sendCommandResponse("delete_single", response);
            } else {
                String response = "格式错误：delete 0x12 0x34 0x56 0x78";
                Serial.println(response);
                sendCommandResponse("delete_single", response);
            }
        }
        else {
            String response = "未知命令，请重试";
            Serial.println(response);
            sendCommandResponse("unknown", response);
        }
    } else {
        // 处理JSON格式的命令
        String commandType = doc["command"].as<String>();
        commandType.toLowerCase();
        
        if (commandType == "write") {
            currentState = WAITING_CARD;
            String response = "请刷卡以注册卡号...";
            Serial.println(response);
            sendCommandResponse("write", response);
        }
        else if (commandType == "read") {
            printAllRegisteredCards();
            String cardList = getAllRegisteredCardsString();
            int count = 0;
            if (cardList.length() > 0) {
                // 计算卡号数量（通过逗号分隔符）
                count = 1;
                for (int i = 0; i < cardList.length(); i++) {
                    if (cardList.charAt(i) == ',') count++;
                }
            }
            sendCardList(cardList, count);
            sendCommandResponse("read", "已获取所有注册的卡号列表");
        }
        else if (commandType == "delete") {
            // 检查是否有指定卡号
            if (doc.containsKey("card_id")) {
                String cardId = doc["card_id"].as<String>();
                byte uid[4];
                
                // 解析卡号字符串为字节数组
                if (cardId.length() == 8) {
                    for (int i = 0; i < 4; i++) {
                        String hexByte = cardId.substring(i * 2, i * 2 + 2);
                        uid[i] = strtol(hexByte.c_str(), NULL, 16);
                    }
                    
                    String response;
                    if (deleteSingleCard(uid)) {
                        response = "单卡删除成功: " + cardId;
                        Serial.println(response);
                    } else {
                        response = "未找到该卡: " + cardId;
                        Serial.println(response);
                    }
                    sendCommandResponse("delete_single", response);
                } else {
                    String response = "卡号格式错误，应为8位十六进制";
                    Serial.println(response);
                    sendCommandResponse("delete_single", response);
                }
            } else {
                deleteAllCards();
                String response = "所有卡号已删除";
                Serial.println(response);
                sendCommandResponse("delete", response);
            }
        }
        else {
            String response = "未知命令: " + commandType;
            Serial.println(response);
            sendCommandResponse("unknown", response);
        }
    }
}

void sendMQTTMessage(const String& message) {
    Serial.print("Sending message to topic: ");
    Serial.println(outTopic);
    Serial.println(message);
    
    bool retained = false;
    int qos = 1;
    bool dup = false;
    
    mqttClient.beginMessage(outTopic, message.length(), retained, qos, dup);
    mqttClient.print(message);
    mqttClient.endMessage();
    
    Serial.println();
}

void sendCardStatus(const String& cardId, bool isRegistered) {
    DynamicJsonDocument json_msg(512);
    DynamicJsonDocument json_data(512);
    
    json_data["type"] = "card_status";
    json_data["card_id"] = cardId;
    json_data["registered"] = isRegistered;
    json_data["timestamp"] = millis();
    
    json_msg["params"] = json_data;
    json_msg["version"] = "1.0";
    
    String payload;
    serializeJson(json_msg, payload);
    sendMQTTMessage(payload);
}

void sendCommandResponse(const String& command, const String& result) {
    DynamicJsonDocument json_msg(512);
    DynamicJsonDocument json_data(512);
    
    json_data["type"] = "command_response";
    json_data["command"] = command;
    json_data["result"] = result;
    json_data["timestamp"] = millis();
    
    json_msg["params"] = json_data;
    json_msg["version"] = "1.0";
    
    String payload;
    serializeJson(json_msg, payload);
    sendMQTTMessage(payload);
}

void sendCardList(const String& cardList, int count) {
    DynamicJsonDocument json_msg(1024);
    DynamicJsonDocument json_data(1024);
    
    json_data["type"] = "card_list";
    json_data["has_cards"] = (count > 0);
    json_data["count"] = count;
    json_data["cards"] = cardList;
    json_data["timestamp"] = millis();
    
    json_msg["params"] = json_data;
    json_msg["version"] = "1.0";
    
    String payload;
    serializeJson(json_msg, payload);
    sendMQTTMessage(payload);
}
